<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片裁剪</title>
    <link type="text/css" rel="stylesheet" href="css/cropper.css">
    <link type="text/css" rel="stylesheet" href="css/imgWorkArea.css">
</head>
<body>
<div class="imgWorkArea">
    <div class="buttonGroup buttonGroupTop">
        <label><input id="imgFile" type="file" onchange="registerCrop()"></label>
<!--        <div id="choseFileBtn" onclick="choseFileHandle()">选择文件</div>-->
<!--        <button onclick="registerCrop()">确认</button>-->
    </div>
    <div class="operationArea">
        <div class="cropperBox">
            <!--裁剪插件 要用的图-->
            <div class="imgBox">
                <img id="clipperImage">
            </div>
            <p class="tipsP">请谨慎使用底图的缩放功能，为保证图片清晰，</p>
            <p class="tipsP">尽量使用缩放裁剪区控制裁剪内容的范围</p>
            <!--翻转 缩放按钮组-->
            <div class="buttonGroup buttonToolsGroup">
                <button onclick="cropControlObj.rotateLeftHandle()">左翻转</button>
                <button onclick="cropControlObj.zoomEnlargeHandle()">放大</button>
                <button onclick="cropControlObj.zoomNarrowHandle()">缩小</button>
                <button onclick="cropControlObj.rotateRightHandle()">右翻转</button>
                <button onclick="cropControlObj.scaleHandle(-1,1)">左右镜像</button>
                <button onclick="cropControlObj.scaleHandle(1,-1)">上下镜像</button>
<!--                <button onclick="cropControlObj.rotateRightHandle()">右翻转</button>-->
            </div>

            <!--快速设置按钮组-->
            <div class="buttonGroup quickSettings">
                <div class="quickBtnS">
                    <button onclick="cropControlObj.clipperSizeHandle(120,90)">120*90</button>
                    <button onclick="cropControlObj.clipperSizeHandle(135,85)">135*85</button>
                    <button onclick="cropControlObj.clipperSizeHandle(140,88)">140*88</button>
                    <button onclick="cropControlObj.clipperSizeHandle(180,100)">180*100</button>
                    <button onclick="cropControlObj.clipperSizeHandle(200,112)">200*112</button>
                    <button onclick="cropControlObj.clipperSizeHandle(320,240)">320*240</button>
                    <button onclick="cropControlObj.clipperSizeHandle(428,240)">428*240</button>
                </div>
                <div class="quickIpt">
                    <input id="clipperWInput" onchange="cropControlObj.clipperWChange()" value="428" placeholder="宽">
                    <span>*</span>
                    <input id="clipperHInput" onchange="cropControlObj.clipperHChange()" value="240" placeholder="高">
                    <button id="quickIptConfirm" onclick="ConfirmProportionHandle()">自定义尺寸确认</button>
                </div>

            </div>
            <!--裁剪预览框 已禁用-->
            <!--<div class="previewBox"></div>-->
            <div class="buttonGroup buttonGroupBottom">
                <button onclick="cropControlObj.resetCropperHandle()">重置裁剪</button>
                <button onclick="getCroppedCanvasHandle()">确认裁剪</button>
            </div>
        </div>
        <div class="chobiBox">
            <!--            <div id="testFilterCanvasBox"></div>-->
            <div class="chobiImgBox">
                <img id="chobiImg">
            </div>
            <p class="tipsP">请注意！当裁剪的宽度超过430px时，预览图会被压缩</p>
            <p class="tipsP">该压缩只影响预览图的观察，不影响该图片的实际使用</p>
            <canvas id="filterCanvas"></canvas>

            <div class="buttonGroup chobiSlider">
                <label>亮度:<input id="brightnessRange" onchange="brightnessChange(this)" type="range" value="0" step="1"
                                min="-20" max="20"></label>
                <label>对比度:<input id="contrastRange" onchange="contrastChange(this)" type="range" value="0" step="1"
                                 min="-20" max="20"></label>
            </div>

            <div class="buttonGroup chobiFilterBtns">
                <button onclick="filter(0)">黑白</button>
                <button onclick="filter(1)">老照片</button>
                <button onclick="filter(2)">反色</button>
                <button onclick="filter(3)">vintage</button>
                <button onclick="filter(4)">crossprocess</button>
                <button onclick="filter(9)">噪点</button>
                <button onclick="filter(11)">Crayon effect</button>
                <button onclick="filter(12)">Cartoonify</button>
            </div>
            <div class="buttonGroup chobiFucBtns">
                <button onclick="reSetHandle()">滤镜效果重置</button>
                <button onclick="downloadImage()">下载图片</button>
                <button onclick="getImgObj()">获取图片对象</button>
            </div>
            <img id="testImg" src="">
        </div>
    </div>
</div>
</body>
<script type="text/javascript" src="js/cropper.min.js"></script>
<script type="text/javascript" src="js/Chobi.min.js"></script>

<script>

    /*比例尺宽高对象*/
    const clipperWInput = document.getElementById('clipperWInput');
    const clipperHInput = document.getElementById('clipperHInput');

    /*定义一个原始图片对象的属性*/
    /*剪切插件*/
    const OriginalAttr = {
        width: 0,
        height: 0,
        url: ''
    };
    /*滤镜用 canvas 画布 对象*/
    const filterCanvas = document.getElementById('filterCanvas');
    /*滤镜用ChobiImg 图 对象*/
    const ChobiImg = document.getElementById('chobiImg');
    /*裁剪区 要上传的file 图 对象*/
    const imgFile = document.getElementById('imgFile');
    /*裁剪工作区 中的 img 对象*/
    const clipperImage = document.getElementById('clipperImage');
    /*裁剪 实例对象*/
    let cropperX = {};
    /*定义一个裁切区域 的宽高属性*/
    const clipperAttr = {
        width: clipperWInput.value,
        height: clipperHInput.value
    };

    let imgChobiObj = null; //全局注册 Chobi 滤镜插件 对象

    let parGlobal = {
        /*保存一个全局对象parGlobal*/
        /*滤镜插件使用*/
        /*contrastNum属性用来存储已经修改的亮度*/
        brightnessNum: 0,
        /*contrastNum用来存储已经修改的对比度*/
        contrastNum: 0
    };

    /*cropper 裁剪插件 的 配置文件*/
    const cropperOptions = {
        aspectRatio: 428 / 240,//需要计算，这是裁剪框显示比例
        viewMode: 2,//显示框模式 0，1，2，3 四种选择
        autoCropArea: 1,//需要计算 这是裁剪框 相对于原图的 比例
        rotatable: true,//旋转图像
        cropBoxResizable: true,//是否通过拖动来调整剪裁框的大小
        // preview: '.previewBox',//裁剪浏览框 已禁用 html要有相应的部分
        dragMode: 'none',
        crop(event) {
            // console.log(event.detail.x);
            // console.log(event.detail.y);

            // console.log(event.detail.width);
            // console.log(event.detail.height);

            /*记录上传的图片的真实 宽 高*/
            OriginalAttr.width = event.detail.width;
            OriginalAttr.height = event.detail.height;

            // console.log(event.detail.rotate);
            // console.log(event.detail.scaleX);
            // console.log(event.detail.scaleY);
        }
    };

    function registerCrop() {
        /*注册裁剪区*/
        /*第一行的注册按钮*/
        /*判断要上传的文件 是否符合标准*/
        if (imgFile.files[0] !== null && imgFile.files[0] !== undefined) {
            let fileType = getFileType(imgFile);
            let imgSize = getFileSize(imgFile);

            /*判断 上传文件 格式 jpg png gif*/
            if (fileType !== "jpg" && fileType !== "png" && fileType !== "gif") {
                if (OriginalAttr.url === '') {}
                imgFile.value = '';
                alert("请上传JPG,PNG,GIF格式的图片");
                return
            }

            /*判断 上传图像 最大尺寸 单位kb*/
            if (imgSize > 2048) {
                imgFile.value = '';
                alert("图片大小不能超过2MB");
                return
            }

            if (OriginalAttr.url === '') {
                /*判断OriginalAttr.url是否为空*/
                /*为空值时，执行新建Clipper对象*/
                /*把上传图设置成要工作区内容*/
                /*把上传的图片生成的临时地址 赋值给image的src路径*/
                clipperImage.src = getObjectURL(imgFile.files[0]);
                registerCropper();
            } else {
                /*不为空时，说明已经创建过一个实例了*/
                /*执行更换url 触发重置*/
                let url = getObjectURL(imgFile.files[0]);
                cropperX.replace(url);
            }
            /*保存之前的url进入OriginalAttr对象的url属性*/
            OriginalAttr.url = getObjectURL(imgFile.files[0]);

        } else {
            alert('请选择要上传的文件')
        }
    }

    function ConfirmProportionHandle() {
        /*确认上传图片尺寸 是否 大于要裁剪的比例*/

        /*上传图片的尺寸*/

        /*记录裁剪尺寸的宽高*/
        clipperAttr.width = parseInt(clipperWInput.value);
        clipperAttr.height = parseInt(clipperHInput.value);

        console.log('原始宽高', OriginalAttr.width, OriginalAttr.height);
        console.log('裁剪宽高', clipperAttr.width, clipperAttr.height);
        /*对比*/
        /*原始尺寸的宽高，要大于裁剪尺寸的宽高*/
        if (OriginalAttr.width >= clipperAttr.width && OriginalAttr.height >= clipperAttr.height) {
            console.log('图片尺寸符合裁剪大于原始图的要求，成功');
            /*设置裁剪比例*/
            cropperOptions.aspectRatio = clipperAttr.width / clipperAttr.height;
            cropperX.setAspectRatio(cropperOptions.aspectRatio)
        } else {
            alert('上传的图片宽或高比裁剪宽高要小，请检查后再重新上传');
        }
    }

    function registerCropper() {
        /*注册裁剪组件*/
        cropperX = new Cropper(clipperImage, cropperOptions);
    }

    const cropControlObj = {
        /*定义一个裁剪对象 方法的 对象*/
        zoomEnlargeHandle() {
            /*放大 按钮*/
            cropperX.zoom(0.1);
        },
        zoomNarrowHandle() {
            /*缩小 按钮*/
            cropperX.zoom(-0.1);
        },
        resetCropperHandle() {
            /*重置按钮*/
            cropperX.reset();
        },
        rotateLeftHandle() {
            /*左翻转*/
            cropperX.rotate(-15);
        },
        rotateRightHandle() {
            /*右翻转*/
            cropperX.rotate(15);
        },
        clipperSizeHandle(width, height) {
            /*快速设置裁切比例方法*/
            /*参数是比例尺的 宽 高*/
            let wInput = clipperWInput;
            let hInput = clipperHInput;
            wInput.value = width;
            hInput.value = height;
            ConfirmProportionHandle()
        },
        clipperWChange() {
            // 设置保存 #clipperWInput 裁剪宽 的值
            clipperAttr.width = document.getElementById('clipperWInput').value;
        },
        clipperHChange() {
            // 设置保存 #clipperHInput 裁剪高 的值
            clipperAttr.height = document.getElementById('clipperHInput').value;
        },
        scaleHandle(x,y){
            cropperX.scale(x,y);
        }
    };

    function getCroppedCanvasHandle() {
        /*返回一张裁切图*/
        /*画一张裁剪图 按钮*/
        /*判断 选取是否会模糊*/

        if (OriginalAttr.width < clipperAttr.width && OriginalAttr.height < clipperAttr.height) {
            alert('设置会模糊,请修改设置');
            return
        }

        /*获取修改后canvas 对象 的配置文件*/
        let options = {
            /*生成canvas所需的选项*/
            fillColor: '#fff',
            width: clipperAttr.width,
            height: clipperAttr.height,
            // minWidth: clipperAttr.width,
            // minHeight: clipperAttr.height,
            // maxWidth: clipperAttr.width,
            // maxHeight: clipperAttr.height,
            imageSmoothingEnabled: true,
            imageSmoothingQuality: 'high',
        };
        /*获取到生成图片的canvas*/
        let canvasObj = cropperX.getCroppedCanvas(options);

        /*canvas转jpg的base64*/
        let imgObj = canvasObj.toDataURL("image/jpeg", 1.0);
        /*为预备好的img 修改他的src属性 使其显示生成的图片*/
        ChobiImg.src = imgObj;
        /*修改滤镜canvas 画布 的尺寸 开始*/
        filterCanvas.style.width = clipperAttr.width;
        filterCanvas.style.heigth = clipperAttr.heigth;
        filterCanvas.width = clipperAttr.width;
        filterCanvas.heigth = clipperAttr.heigth;
        /*修改滤镜canvas 画布 的尺寸 结束*/
        /*初始化滤镜*/
        setTimeout(function () {
            getChildren()
        }, 300)
    }

    /*滤镜插件 方法 开始*/
    function loadImage(elem) {
        // 初始化chobi文件
        //you should probably check if file is image or not before passing it
        imgChobiObj = new Chobi(elem);
        imgChobiObj.ready(function () {
        });
        imgChobiObj.canvas = document.getElementById("filterCanvas");
        imgChobiObj.loadImageToCanvas();
    }

    function downloadImage() {
        /*下载图片*/
        if (imgChobiObj === null) {
            alert('下载图片失败');
            return;
        }
        imgChobiObj.xwyDownload('dome_img', 'jpg',clipperAttr.width,clipperAttr.height);
    }

    function reSetHandle() {
        /*滤镜重置*/
        /*恢复滑块内容*/
        document.getElementById('brightnessRange').value = 0;
        document.getElementById('contrastRange').value = 0;
        // 滤镜 效果恢复默认
        loadImage(ChobiImg)
    }

    function filter(id) {
        /*滤镜按钮*/
        //0 -> Black and white
        //10 -> Black and white2
        //1 -> sepia
        //2 -> negative
        //3 -> vintage
        //4 -> crossprocess
        //5 -> Brightness +
        //6 -> Brightness -
        //7 -> Contrast +
        //8 -> Contrast -
        //9 -> Noise Effect
        //11 -> Crayon effect
        //12 -> Cartoonify
        //13 -> Vignette
        /*可用过滤链*/
        //filter chaining is also possible, like imgChobiObj.brightness(-5).sepia().negative();
        switch (id) {
            case 0:
                imgChobiObj.blackAndWhite();
                break;
            case 1:
                imgChobiObj.sepia();
                break;
            case 2:
                imgChobiObj.negative();
                break;
            case 3:
                imgChobiObj.vintage();
                break;
            case 4:
                imgChobiObj.crossProcess();
                break;
            case 9:
                imgChobiObj.noise();
                break;
            case 11:
                imgChobiObj.crayon();
                break;
            case 12:
                imgChobiObj.cartoon();
                break;
            default:
                alert("未定义的滤镜属性，请检查");
        }
        imgChobiObj.loadImageToCanvas();
    }

    function getImgObj() {
        // console.log(1)
        /*滤镜插件用*/
        /*获取图像对象*/
        // let imgObj = imgChobiObj.getImage();
        // let src = imgObj.getImage();
        // console.log(imgObj);
        // console.log(imgObj.src);
        // document.getElementById('testImg').src = imgObj.src;
    }

    function brightnessChange(ele) {
        /*滑动 修改图片的 亮度*/
        /*本次要修改的数值*/
        let newNum = parseInt(ele.value);
        /*上次修改了的数值*/
        let oldNum = parGlobal.brightnessNum;
        /*要修改的数值是本次要修改的减去上次已经修改的*/
        imgChobiObj.brightness(newNum - oldNum);
        /*重新绘制*/
        imgChobiObj.loadImageToCanvas();
        /*本次要修改的数值 保存为全局变量 以备下次使用*/
        parGlobal.brightnessNum = newNum;
    }

    function contrastChange(ele) {
        /*滑动 修改图片的 对比度*/
        /*本次要修改的数值*/
        let newNum = parseInt(ele.value);
        /*上次修改了的数值*/
        let oldNum = parGlobal.contrastNum;
        /*要修改的数值是本次要修改的减去上次已经修改的*/
        imgChobiObj.contrast(newNum - oldNum);
        /*重新绘制*/
        imgChobiObj.loadImageToCanvas();
        /*本次要修改的数值 保存为全局变量 以备下次使用*/
        parGlobal.contrastNum = newNum;
    }

    function getChildren() {
        /*初始化滤镜插件 按钮*/
        /*找到要渲染的画布*/
        /*滤镜用 canvas 画布*/
        loadImage(ChobiImg);
    }
    /*滤镜插件 方法 结束*/


/*全局方法 开始*/

    function getObjectURL(file) {
        /*获取上传的 临时文件 路径*/
        /*参数 file 是要获取路径的文件*/
        let url = null;
        if (window.createObjcectURL !== undefined) {
            url = window.createOjcectURL(file);
        } else if (window.URL !== undefined) {
            url = window.URL.createObjectURL(file);
        } else if (window.webkitURL !== undefined) {
            url = window.webkitURL.createObjectURL(file);
        }
        return url;
    }

    function getFileSize(File) {
        /*获取 所传对象的 size*/
        /*File 参数 是要检测的文件对象*/
        /*返回数据的单位是 kb*/
        /*用于检测*/
        return File.files[0].size / 1024
    }

    function getFileType(File) {
        /*获取上传文件的 文件类型 扩展名*/
        /*File 参数 是要检测的文件对象*/
        let filePath = File.files[0].name;
        let startIndex = filePath.lastIndexOf(".");
        if (startIndex !== -1)
            return filePath.substring(startIndex + 1, filePath.length).toLowerCase();
        else return "";
    }

    /*Base64转File*/
    function Base64toFile(dataurl, filename) {//将base64转换为文件
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {type: mime});
    }

    /*Base64 url转Blob*/
    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {type: mime});
    }

    /*伪装上传按钮*/
    function choseFileHandle() {
        // imgFile
        let btnText;
        document.getElementById('imgFile').click();
        btnText = document.getElementById('imgFile').files[0].name || '未上传文件';
        document.getElementById('choseFileBtn').innerText = btnText;
    }

    /*全局方法 结束*/
    window.onload = function () {
        /*测试用 默认加载裁切图 开始*/
        // registerCropper()
        /*测试用 默认加载裁切图 结束*/
    };


</script>

</html>
